package cn.source.web.controller.db;

import cn.source.common.constant.HttpStatus;
import cn.source.common.core.controller.BaseController;
import cn.source.common.core.domain.AjaxResult;
import cn.source.common.core.page.TableDataInfo;
import cn.source.zk.domain.dto.*;
import cn.source.zk.domain.entity.*;
import cn.source.zk.domain.vo.DbAggDataVO;
import cn.source.zk.service.IDbBaseDataService;
import cn.source.zk.service.ZkSettingQueryFieldsService;
import com.github.abel533.echarts.axis.CategoryAxis;
import com.github.abel533.echarts.axis.ValueAxis;
import com.github.abel533.echarts.code.SeriesType;
import com.github.abel533.echarts.code.Tool;
import com.github.abel533.echarts.code.Trigger;
import com.github.abel533.echarts.json.GsonOption;
import com.github.abel533.echarts.series.Line;
import com.github.abel533.echarts.series.Series;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/zk/baseData")
@Slf4j
public class BaseDataController extends BaseController {

    @Autowired
    private IDbBaseDataService dbBaseDataService;

    @Autowired
    private ZkSettingQueryFieldsService zkSettingQueryFieldsService;

    @GetMapping("/flowLineAverage")
    @ResponseBody
    public String flowLineAverage(BaseDataQueryDTO baseDataQueryDTO) {
        if (baseDataQueryDTO.getDateType() == null) {
            baseDataQueryDTO.setDateType("day");
        }
        List<Map<String, Object>> list = dbBaseDataService.selectByDateAverage(baseDataQueryDTO);
        log.info("查询出来的数据:{}", list);
        return echartsData(list, "average_", "电能质量平均值");
    }

    @GetMapping("/flowLineMax")
    @ResponseBody
    public String flowLineMax(BaseDataQueryDTO baseDataQueryDTO) {
        if (baseDataQueryDTO.getDateType() == null) {
            baseDataQueryDTO.setDateType("day");
        }
        List<Map<String, Object>> list = dbBaseDataService.selectByDateMax(baseDataQueryDTO);
        log.info("查询出来的数据:{}", list);
        return echartsData(list, "max_", "电能质量最大值");
    }

    @GetMapping("/flowLineMin")
    @ResponseBody
    public String flowLineMin(BaseDataQueryDTO baseDataQueryDTO) {
        if (baseDataQueryDTO.getDateType() == null) {
            baseDataQueryDTO.setDateType("day");
        }
        List<Map<String, Object>> list = dbBaseDataService.selectByDateMin(baseDataQueryDTO);
        log.info("查询出来的数据:{}", list);
        return echartsData(list, "min_", "电能质量最小值");
    }


    private String echartsData(List<Map<String, Object>> list, String prefix, String title) {
        log.info("查询出来的数据:{}", list);

        Object[] dateTypes = list.stream()
                .filter(map -> map.containsKey("date"))
                .map(map -> map.get("date"))
                .toArray();

        String[] names = {"ua", "ub", "uc"};

        // 使用流式编程获取所有键名前缀为 "average_" 的值，并组织成二维数组
        Map<String, List<Object>> averageValuesMap = list.stream()
                // 转换为键值对流
                .flatMap(map -> map.entrySet().stream())
                // 过滤出键名前缀为 "average_" 的条目
                .filter(entry -> entry.getKey().startsWith(prefix))
                // 收集成 Map，键为原始键名，值为值的列表
                .collect(Collectors.groupingBy(
                        Map.Entry::getKey,
                        Collectors.mapping(Map.Entry::getValue, Collectors.toList())
                ));

        // 让hashMap排序
        LinkedHashMap<String, List<Object>> sortedAverageValuesMap = averageValuesMap.entrySet()
                .stream()
                .sorted(Map.Entry.comparingByKey())
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        Map.Entry::getValue,
                        (e1, e2) -> e1, // 如果有相同的键，保留第一个
                        LinkedHashMap::new // 使用LinkedHashMap来保持插入顺序
                ));

        // 将 Map 转换为二维数组
        // 提取所有值并放入数组中
        Object[][] datas = new Object[sortedAverageValuesMap.size()][];
        int index = 0;

        for (List<Object> value : sortedAverageValuesMap.values()) {
            Object[] array = value.toArray();
            datas[index++] = array;
        }


        List<Series> series = Lists.newArrayList();

        for (int i = 0; i < names.length; i++) {
            Line line = new Line();
            line.name(names[i]);
            for (int x = 0; x < datas[i].length; x++) {
                line.data(datas[i][x]);
            }
            line.type(SeriesType.line);
            // line.stack("Total");
            series.add(line);
        }
        GsonOption option = new GsonOption();
        option.series(series);
        option.title().text(title).x("left");
        option.tooltip().show(true).trigger(Trigger.axis);
        option.toolbox().show(false).feature(Tool.magicType, Tool.dataZoom);
        CategoryAxis categoryAxis = new CategoryAxis();
        option.xAxis(categoryAxis);
        ValueAxis valueAxis = new ValueAxis();
        valueAxis.max(58);
        valueAxis.min(55);
        valueAxis.splitNumber(10);
        option.yAxis(valueAxis);
        categoryAxis.data(dateTypes);
        return option.toString();
    }

    /**
     * 图表数据
     * ========================================================
     * 表格数据
     */

    @GetMapping("/list")
    public TableDataInfo getBaseData(BaseData2TableDTO baseData2TableDTO) {
        log.info("基础数据"+baseData2TableDTO);
        startPage();
        List<DbBaseData> list = dbBaseDataService.getBaseDataList(baseData2TableDTO);
        return getDataTable(list);
    }

    /**
     * 获取DBIhra数据
     * @param baseData2TableDTO
     * @return
     */
    @GetMapping("/ihra/list")
    public TableDataInfo getDbIhra(BaseData2TableDTO baseData2TableDTO){
        startPage();
        List<DBIhra> list = dbBaseDataService.getDbIhra(baseData2TableDTO);
        return getDataTable(list);
    }

    @GetMapping("/ihrb/list")
    public TableDataInfo getDbIhrb(BaseData2TableDTO baseData2TableDTO){
        startPage();
        List<DBIhrb> list = dbBaseDataService.getDbIhrb(baseData2TableDTO);
        return getDataTable(list);
    }

    @GetMapping("/ihrc/list")
    public TableDataInfo getDbIhrc(BaseData2TableDTO baseData2TableDTO){
        startPage();
        List<DBIhrc> list = dbBaseDataService.getDbIhrc(baseData2TableDTO);
        return getDataTable(list);
    }

    @GetMapping("/ihrja/list")
    public TableDataInfo getDbIhrja(BaseData2TableDTO baseData2TableDTO){
        startPage();
        List<DBIhrja> list = dbBaseDataService.getDbIhrja(baseData2TableDTO);
        return getDataTable(list);
    }

    @GetMapping("/ihrjb/list")
    public TableDataInfo getDbIhrjb(BaseData2TableDTO baseData2TableDTO){
        startPage();
        List<DBIhrjb> list = dbBaseDataService.getDbIhrjb(baseData2TableDTO);
        return getDataTable(list);
    }

    @GetMapping("/ihrjc/list")
    public TableDataInfo getDbIhrjc(BaseData2TableDTO baseData2TableDTO){
        startPage();
        List<DBIhrjc> list = dbBaseDataService.getDbIhrjc(baseData2TableDTO);
        return getDataTable(list);
    }

    @GetMapping("/uhra/list")
    public TableDataInfo getDbUhra(BaseData2TableDTO baseData2TableDTO){
        startPage();
        List<DBUhra> list = dbBaseDataService.getDbUhra(baseData2TableDTO);
        return getDataTable(list);
    }

    @GetMapping("/uhrb/list")
    public TableDataInfo getDbUhrb(BaseData2TableDTO baseData2TableDTO){
        startPage();
        List<DBUhrb> list = dbBaseDataService.getDbUhrb(baseData2TableDTO);
        return getDataTable(list);
    }

    @GetMapping("/uhrc/list")
    public TableDataInfo getDbUhrc(BaseData2TableDTO baseData2TableDTO){
        startPage();
        List<DBUhrc> list = dbBaseDataService.getDbUhrc(baseData2TableDTO);
        return getDataTable(list);
    }

    @GetMapping("/uhrja/list")
    public TableDataInfo getDbUhrja(BaseData2TableDTO baseData2TableDTO){
        startPage();
        List<DBUhrja> list = dbBaseDataService.getDbUhrja(baseData2TableDTO);
        return getDataTable(list);
    }

    @GetMapping("/uhrjb/list")
    public TableDataInfo getDbUhrjb(BaseData2TableDTO baseData2TableDTO){
        startPage();
        List<DBUhrjb> list = dbBaseDataService.getDbUhrjb(baseData2TableDTO);
        return getDataTable(list);
    }

    @GetMapping("/uhrjc/list")
    public TableDataInfo getDbUhrjc(BaseData2TableDTO baseData2TableDTO){
        startPage();
        List<DBUhrjc> list = dbBaseDataService.getDbUhrjc(baseData2TableDTO);
        return getDataTable(list);
    }

    /**
     * 获取汇总数据
     * @return
     */
    @PostMapping("/getAggData")
    public AjaxResult getAggData(@RequestBody DbAllIndicatorsDTO dbAllIndicatorsDTO){

        List<DbAggDataVO> list = dbBaseDataService.getAggData(dbAllIndicatorsDTO);

        return AjaxResult.success(list);
    }

    @GetMapping("/dbIhr/list")
    public TableDataInfo getDbIhr(BaseData2TableDTO baseData2TableDTO,@RequestParam(required = false) Integer pageNum,@RequestParam(required = false)  Integer pageSize){
        List<DBIhrDTO> list = dbBaseDataService.getDbIhr(baseData2TableDTO);

        // 将DTO转换为扁平化的Map结构
        List<Map<String, Object>> flattenedData = list.stream()
                .map(dto -> {
                    Map<String, Object> item = new HashMap<>();
                    item.put("timedate", dto.getTimedate());

                    // 将fields中的所有字段直接添加到item中
                    dto.getFields().forEach((key, value) -> {
                        // 去掉前缀，直接使用原始字段名
                        String fieldName = key.substring(2); // 去掉"a_", "b_", "c_"前缀
                        item.put(fieldName, value);
                    });

                    return item;
                })
                .collect(Collectors.toList());

        // 构建返回数据
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setMsg("查询成功");

        // 判断是否需要分页
        if (pageNum != null && pageSize != null) {
            // 总记录数
            int total = flattenedData.size();

            // 手动分页
            int startIndex = (pageNum - 1) * pageSize;
            int endIndex = Math.min(startIndex + pageSize, flattenedData.size());

            List<Map<String, Object>> pageList = startIndex >= flattenedData.size() ?
                    new ArrayList<>() :
                    flattenedData.subList(startIndex, endIndex);

            rspData.setRows(pageList);
            rspData.setTotal(total);
        } else {
            // 不分页，返回所有数据
            rspData.setRows(flattenedData);
            rspData.setTotal(flattenedData.size());
        }

        return rspData;
    }

    @GetMapping("/dbIhrj/list")
    public TableDataInfo getDbIhrj(BaseData2TableDTO baseData2TableDTO,@RequestParam(required = false)  Integer pageNum,@RequestParam(required = false)  Integer pageSize){

        List<DBIhrjDTO> list = dbBaseDataService.getDbIhrj(baseData2TableDTO);

        // 将DTO转换为扁平化的Map结构
        List<Map<String, Object>> flattenedData = list.stream()
                .map(dto -> {
                    Map<String, Object> item = new HashMap<>();
                    item.put("timedate", dto.getTimedate());

                    // 将fields中的所有字段直接添加到item中
                    dto.getFields().forEach((key, value) -> {
                        // 去掉前缀，直接使用原始字段名
                        String fieldName = key.substring(2); // 去掉"a_", "b_", "c_"前缀
                        item.put(fieldName, value);
                    });

                    return item;
                })
                .collect(Collectors.toList());

        // 构建返回数据
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setMsg("查询成功");

        // 判断是否需要分页
        if (pageNum != null && pageSize != null) {
            // 总记录数
            int total = flattenedData.size();

            // 手动分页
            int startIndex = (pageNum - 1) * pageSize;
            int endIndex = Math.min(startIndex + pageSize, flattenedData.size());

            List<Map<String, Object>> pageList = startIndex >= flattenedData.size() ?
                    new ArrayList<>() :
                    flattenedData.subList(startIndex, endIndex);

            rspData.setRows(pageList);
            rspData.setTotal(total);
        } else {
            // 不分页，返回所有数据
            rspData.setRows(flattenedData);
            rspData.setTotal(flattenedData.size());
        }

        return rspData;
    }

    @GetMapping("/dbUhr/list")
    public TableDataInfo getDbUhr(BaseData2TableDTO baseData2TableDTO,@RequestParam(required = false)  Integer pageNum,@RequestParam(required = false)  Integer pageSize){
        List<DBUhrDTO> list = dbBaseDataService.getDbUhr(baseData2TableDTO);

        // 将DTO转换为扁平化的Map结构
        List<Map<String, Object>> flattenedData = list.stream()
                .map(dto -> {
                    Map<String, Object> item = new HashMap<>();
                    item.put("timedate", dto.getTimedate());

                    // 将fields中的所有字段直接添加到item中
                    dto.getFields().forEach((key, value) -> {
                        // 去掉前缀，直接使用原始字段名
                        String fieldName = key.substring(2); // 去掉"a_", "b_", "c_"前缀
                        item.put(fieldName, value);
                    });

                    return item;
                })
                .collect(Collectors.toList());

        // 构建返回数据
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setMsg("查询成功");

        // 判断是否需要分页
        if (pageNum != null && pageSize != null) {
            // 总记录数
            int total = flattenedData.size();

            // 手动分页
            int startIndex = (pageNum - 1) * pageSize;
            int endIndex = Math.min(startIndex + pageSize, flattenedData.size());

            List<Map<String, Object>> pageList = startIndex >= flattenedData.size() ?
                    new ArrayList<>() :
                    flattenedData.subList(startIndex, endIndex);

            rspData.setRows(pageList);
            rspData.setTotal(total);
        } else {
            // 不分页，返回所有数据
            rspData.setRows(flattenedData);
            rspData.setTotal(flattenedData.size());
        }

        return rspData;
    }

    @GetMapping("/dbUhrj/list")
    public TableDataInfo getDbUhrj(BaseData2TableDTO baseData2TableDTO,@RequestParam(required = false)  Integer pageNum,@RequestParam(required = false)  Integer pageSize){

        List<DBUhrjDTO> list = dbBaseDataService.getDbUhrj(baseData2TableDTO);

        // 将DTO转换为扁平化的Map结构
        List<Map<String, Object>> flattenedData = list.stream()
                .map(dto -> {
                    Map<String, Object> item = new HashMap<>();
                    item.put("timedate", dto.getTimedate());

                    // 将fields中的所有字段直接添加到item中
                    dto.getFields().forEach((key, value) -> {
                        // 去掉前缀，直接使用原始字段名
                        String fieldName = key.substring(2); // 去掉"a_", "b_", "c_"前缀
                        item.put(fieldName, value);
                    });

                    return item;
                })
                .collect(Collectors.toList());

        // 构建返回数据
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setMsg("查询成功");

        // 判断是否需要分页
        if (pageNum != null && pageSize != null) {
            // 总记录数
            int total = flattenedData.size();

            // 手动分页
            int startIndex = (pageNum - 1) * pageSize;
            int endIndex = Math.min(startIndex + pageSize, flattenedData.size());

            List<Map<String, Object>> pageList = startIndex >= flattenedData.size() ?
                    new ArrayList<>() :
                    flattenedData.subList(startIndex, endIndex);

            rspData.setRows(pageList);
            rspData.setTotal(total);
        } else {
            // 不分页，返回所有数据
            rspData.setRows(flattenedData);
            rspData.setTotal(flattenedData.size());
        }

        return rspData;
    }

}
